package com.tl.commonlibrary.ui;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;

import com.tl.commonlibrary.AppConfig;
import com.tl.commonlibrary.BuildConfig;
import com.tl.commonlibrary.tool.Logger;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

/**
 * Activity启动和退出的堆栈管理
 *
 * @author SunJm
 * @date 2013-10-17
 */
public class ActivityStack {

    private static Stack<WeakReference<Activity>> activityStack = new Stack<WeakReference<Activity>>();
    private static ActivityStack instance;

    private ActivityStack() {

    }

    private int startedSize = 0;

    public static ActivityStack get() {
        if (instance == null) {
            instance = new ActivityStack();
        }
        return instance;
    }

    /**
     * 获取指定Activity类的实例个数
     *
     * @param baseActivityClass
     * @return
     */
    public int getCountByClass(Class baseActivityClass) {
        return has(baseActivityClass);
    }

    /**
     * 栈中是否存在baseActivityClass的实例
     *
     * @param baseActivityClass
     * @return 返回有多少个baseActivityClass的实例存在栈中
     */
    public int has(Class baseActivityClass) {
        int count = 0;
        for (int i = 0; i < activityStack.size(); i++) {
            WeakReference<Activity> weakReference = activityStack.get(i);
            if (weakReference != null) {
                Activity act = weakReference.get();
                if (act != null && baseActivityClass.equals(act.getClass())) {
                    count++;
                }
            }
        }
        Logger.e("", "hasActivity " + baseActivityClass + " and the cout is " + count);

        return count;
    }

    /**
     * 栈中是否存在baseActivity
     *
     * @param baseActivity
     * @return 是否存在该实例
     */
    public boolean has(Activity baseActivity) {
        for (int i = 0; i < activityStack.size(); i++) {
            WeakReference<Activity> weakReference = activityStack.get(i);
            if (weakReference != null) {
                Activity act = weakReference.get();
                if (act != null && act == baseActivity) {
                    Logger.e("", "hasActivity instance" + baseActivity);
                    return true;
                }
            }
        }
        if (AppConfig.DEBUG()) {
            Logger.e("", "hasActivity NO instance" + baseActivity);
        }
        return false;
    }

    /**
     * 退出指定的Activity
     *
     * @param activity
     */
    public void pop(Activity activity) {
        if (activity != null) {
            // 在从自定义集合中取出当前Activity时，也进行了Activity的关闭操作
            WeakReference<Activity> weakReference = null;
            for (int i = 0; i < activityStack.size(); i++) {
                weakReference = activityStack.get(i);
                if (weakReference != null && weakReference.get() == activity) {
                    activityStack.remove(weakReference);
                    Logger.e("", "popActivity activity" + activity);
                    break;
                }
            }
            activity.finish();
        }
    }

    /**
     * 退出指定的Activity
     *
     * @param activity
     */
    public void onDestroy(Activity activity) {
        if (activity != null) {
            // 在从自定义集合中取出当前Activity时，也进行了Activity的关闭操作
            WeakReference<Activity> weakReference = null;
            for (int i = 0; i < activityStack.size(); i++) {
                weakReference = activityStack.get(i);
                if (weakReference != null && weakReference.get() == activity) {
                    activityStack.remove(weakReference);
                    Logger.e("", "popActivity activity" + activity);
                    break;
                }
            }
        }
    }

    /**
     * 退出指定的Activity
     *
     * @param clazz
     */
    public boolean popByClass(Class clazz) {
        if (clazz != null) {
            // 在从自定义集合中取出当前Activity时，也进行了Activity的关闭操作
            WeakReference<Activity> weakReference = null;
            for (int i = 0; i < activityStack.size(); i++) {
                weakReference = activityStack.get(i);
                if (weakReference != null) {
                    Activity act = weakReference.get();
                    if (act != null && act.getClass().equals(clazz)) {
                        activityStack.remove(weakReference);
                        Logger.e("", "popActivity activity by Class " + clazz);
                        act.finish();
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 退出栈顶的activity
     *
     * @return
     */
    public void popCurrent() {
        if (!activityStack.isEmpty()) {
            WeakReference<Activity> curWeakReference = activityStack.pop();
            if (curWeakReference != null) {
                Activity curActivity = curWeakReference.get();
                if (curActivity != null) {
                    curActivity.finish();
                }
            }
        }
    }

    /**
     * 退出指定class类以上的实例
     *
     * @param clazz
     */
    public Activity popUntil(Class clazz) {
        if (!activityStack.isEmpty()) {
            if (has(clazz) > 0) {
                int size = activityStack.size();
                WeakReference<Activity> weakReference;
                Activity activity ;
                while (--size >= 0) {
                    weakReference = activityStack.peek();
                    if (weakReference != null) {
                        activity = weakReference.get();
                        if (activity != null) {
                            if (activity.getClass() == clazz) {
                                return activity;
                            } else {
                                activityStack.pop();
                                activity.finish();
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获得当前栈顶Activity
     */
    public Activity current() {
        if (!activityStack.empty()) {
            WeakReference<Activity> weakReference = activityStack.lastElement();
            if (weakReference != null) {
                Logger.e("", "currentActivity " + weakReference.get());
                return weakReference.get();
            }
        }
        return null;
    }

    public Activity currentBaseFragmentActivity() {
        Activity activity;
        final int len = activityStack.size();
        for (int i = len - 1; i >= 0; i--) {
            WeakReference<Activity> weakReference = activityStack.get(i);
            if (weakReference != null) {
                activity = weakReference.get();
                if (activity != null && activity instanceof BaseFragmentActivity) {
                    return activity;
                }
            }
        }
        return null;
    }

    /**
     * 通过类名获取该类处在Stack中栈顶的activity实例
     *
     * @param clazz
     * @return
     */
    public Activity getActivityByClass(Class clazz) {
        for (int i = 0; i < activityStack.size(); i++) {
            WeakReference<Activity> weakReference = activityStack.get(i);
            if (weakReference != null) {
                Activity act = weakReference.get();
                if (act != null && clazz.equals(act.getClass())) {
                    return act;
                }
            }
        }
        return null;
    }

    /**
     * 通过类名 获取该类在栈中存在的的所有实例
     *
     * @param clazz
     * @return
     */
    public List<Activity> getActivitiesByClass(Class clazz) {
        List<Activity> activities = new ArrayList<Activity>();
        for (int i = 0; i < activityStack.size(); i++) {
            WeakReference<Activity> weakReference = activityStack.get(i);
            if (weakReference != null) {
                Activity act = weakReference.get();
                if (act != null && clazz.equals(act.getClass())) {
                    activities.add(act);
                }
            }
        }
        return activities;
    }

    public boolean onCreate(Activity activity) {
        return push(activity);
    }

    // 将当前Activity推入栈中
    public boolean push(Activity activity) {
        if (activityStack == null) {
            activityStack = new Stack<>();
        }
        if (has(activity)) {
            if (AppConfig.DEBUG()) {
                Logger.e("", "pushActivity failed " + activity);
            }
            return false;
        }
        WeakReference<Activity> weakReference = new WeakReference<>(activity);
        activityStack.add(weakReference);
        Logger.e("", "pushActivity success " + activity);
        return true;
    }

    /**
     * 退出所有activity
     */
    public void popAll() {
        popAllExceptInstance(null);
    }

//    /**
//     * 退出栈中所有Activity除了cls指定的所有实例activity
//     *
//     * @param cls all its instance (activitys)  will be left.
//     */
//    public void popAllExceptClass(Class cls) {
//        Iterator<WeakReference<Activity>> it = activityStack.iterator();
//        int size = activityStack.size();
//        WeakReference<Activity> weakReference = null;
//        WeakReference<Activity> leaftWeakReference = null;
//        Activity activity = null;
//        while (--size >= 0) {
//            weakReference = activityStack.peek();
//            if (weakReference != null) {
//                activity = weakReference.get();
//                activityStack.pop();
//                if (activity != null && activity.getClass() != cls) {
//                    activity.finish();
//                }else{
//                    leaftWeakReference = weakReference;
//                }
//            }
//        }
//        if(weakReference != null){
//            activityStack.push(leaftWeakReference);
//        }
//    }

    /**
     * 退出栈中所有Activity除了cls指定的所有实例activity
     *
     * @param cls all its instance (activitys)  will be left.
     */
    public void popAllExceptClass(Class cls) {
//        Iterator<WeakReference<Activity>> it = activityStack.iterator();
        int size = activityStack.size();
        WeakReference<Activity> weakReference = null;
        WeakReference<Activity> leaftWeakReference = null;
        Activity activity;
        while (--size >= 0) {
            weakReference = activityStack.peek();
            if (weakReference != null) {
                activity = weakReference.get();
                activityStack.pop();
                if (activity != null && activity.getClass() != cls) {
                    activity.finish();
                } else {
                    leaftWeakReference = weakReference;
                }
            }
        }
        if (weakReference != null) {
            activityStack.push(leaftWeakReference);
        }
    }

    /**
     * 退出栈中所有Activity除了leftActivity
     *
     * @param leftActivity the activity instance left.
     */
    public void popAllExceptInstance(Activity leftActivity) {
//        Iterator<WeakReference<Activity>> it = activityStack.iterator();
        int size = activityStack.size();
        WeakReference<Activity> weakReference;
        Activity activity;
        while (--size >= 0) {
            if (activityStack.isEmpty()) {
                return;
            }
            weakReference = activityStack.peek();
            if (weakReference != null) {
                activity = weakReference.get();
                if (activity != null && activity != leftActivity) {
                    activityStack.pop();
                    activity.finish();
                    if (BuildConfig.DEBUG) {
                        Logger.e("", "Subject popActivity success " + activity);
                    }
                }
            }
        }
    }

    /**
     * 退出应用程序
     */
    public void appExit(Context context) {
        try {
//            StatisticEntrance entrance = PluginManager.get().getStatisticEntrance();
//            if (entrance != null) {
//                entrance.setAppEndTime(System.currentTimeMillis());
//                entrance.backups();//备份行为数据，下次启动app上传
//            }
            popAll();
            ActivityManager activityMgr = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            if (context instanceof Activity) {
                ((Activity) context).finish();
            }
            activityMgr.killBackgroundProcesses(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {
        }
    }

    /**
     * 当前栈中Activity的实例总个数
     *
     * @return
     */
    public int getSizeUseful() {
        int count = 0;
        if (activityStack != null) {
            WeakReference<Activity> weakReference;
            for (int i = 0; i < activityStack.size(); i++) {
                weakReference = activityStack.peek();
                if (weakReference != null && weakReference.get() != null) {
                    count++;
                }
            }
        }
        return count;
    }

    public void onStarted(Activity activity) {
        startedSize++;
    }

    public void onStop(Activity activity) {
        startedSize--;
    }

    public boolean isAppForeground() {
        return startedSize > 0;
    }

    /**
     * 当前栈中被系统回收或者手动finish的实例个数，不包括调用{@link #pop(Activity)}{@link #popCurrent()} 等销毁的实例
     *
     * @return
     */
    public int getSizeUnUseful() {
        return activityStack.size() - getSizeUseful();
    }
}
